使用一元运算符多次管道

Piping multilpe times using unary operator

我有以下功能:

Function Refine{
    [CmdletBinding()]
        param (
            [parameter(ValueFromPipeline = $true)]
          $data
        )
        begin {}
        process {
            For ($i=0; $i -le $data.count; $i++){
            if ($data[$i] -match 'nmap scan report' -and $data[$i+1] -match 'host is up' )  {
                $dat += $data[$i] + "`n"
                $counter=($i+4)
                while ($data[$counter] -match '^[0-9]') {
                    $dat += $data[$counter] + "`n"
                    $counter++
                }        
                }
            }
            
         }
        end { 
            if ($dat){#See that its not empty
            return  $dat.Split([Environment]::NewLine)
            }
        }
    }

$file1 = gc c:\test.txt

,gc ($file1) | Refine

我必须使用一元运算符进行管道传输,因为我希望将整个对象一次性传输到优化函数。

例如,输出是这样的: 1.1.1.1 的 Nmap 扫描报告 113/tcp 关闭标识 443/tcp 打开 ssl/http Fortinet SSL VPN 2.2.2.2 的 Nmap 扫描报告 21/tcp 过滤 ftp 22/tcp 过滤 ssh

我现在想使用另一个函数,它接受这个并从文本创建对象:

  Function BuildArray{
      [CmdletBinding()]
      Param(
          [Parameter(ValueFromPipeline = $true)]
          $data
      )
      Begin {}
      Process {
        $NMAPS=@()
        $nmap=@()
        $ports=@()
        For ($i=0; $i -lt $data.count; $i++){
            If ($data[$i] -match 'nmap scan report')  {
            $ip = ($data[$i] |  Select-String -Pattern "\d{1,3}(\.\d{1,3}){3}" -AllMatches).Matches.Value
            $k=$i
            If ($data[($i+1)] -notmatch 'nmap scan report' -and $i -le $data.count){
                DO{
                $ports+=$data[$i+1]
                $i++
                }
               While ($data[$i+1] -notmatch 'nmap scan report' -and $i -le $data.count)
               $nmap = @{IP = "$ip"; ports=@($ports)}
               $NMAPS+=$nmap
               $nmap=@()
               $ports=@()
               $i = $k
               }
              }
            }
      }
      End {
        $NMAPS
      }
  }

我的问题又来了——我希望管道中的数据作为一个整体传递给 BuildArray 函数。但我不能使用一元运算符,因为我收到一条错误消息,说我只能在管道的开头使用它,

 ,(gc $file1 ) | ,(refine) | BuildArray #No good

如何将管道中的第二个对象作为一个整体一次性传递给第三个对象?

恕我直言,您对 PowerShell pipeline. Cmdlets should implement for the Middle of a Pipeline 的一般概念并不正确,这意味着每个 cmdlet 都应该处理每个项目 a.s.a.p。 将其流到下一个cmdlet,最终将其从内存中释放。
PowerShell 对象 (PSCustomObjects) 针对流式处理进行了优化,因为它包含其属性的所有类型信息。这使得这些 PowerShell 对象很重,不太适合将它们存储在(大)集合中。
特定于您自己的功能,它使您的 input processing methods (the Start, Process and End block structure) pointless which is especially developed to Process each specific object in the pipeline. If you collect all your objects in an array before passing it to your BuildArray function, you might as well just use the End block (or leave all the input blocks which is similar to just an End block) where the automated $Input variable 管道中提供的所有对象 保存在一个数组中:

Function BuildArray {
    [CmdletBinding()]
    Param(
        [Parameter(ValueFromPipeline = $true)]$data
    )
    Process { Write-Host 'Process:' $Input }
}

1,2,3 | BuildArray

Process: 1
Process: 2
Process: 3

Function BuildArray {
    [CmdletBinding()]
    Param(
        [Parameter(ValueFromPipeline = $true)]$data
    )
    End { Write-Host 'End:' $Input } # or just: Write-Host $Input
}

1,2,3 | BuildArray

End: 1 2 3

另外: